/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.losalpes.client;

import com.losalpes.persistence.IPersistenceServices;
import com.losalpes.persistence.entity.Ciudad;
import com.losalpes.persistence.entity.Cliente;
import com.losalpes.persistence.entity.Departamento;
import com.losalpes.persistence.entity.Pais;
import com.losalpes.persistence.entity.TipoDocumento;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.faces.model.SelectItem;

/**
 *
 * @author Henry.Quiroga
 */
@Stateless
@DeclareRoles({"Administrador"})
public class ClientService implements IClientService {

    @EJB
    IPersistenceServices persistenceServices;

    /**
     * constructor de la clase
     */
    public ClientService() {
    }

    /**
     * Almacena un cliente
     * @param cliente
     * @return
     */
    public void save(Cliente cliente) {
        if (cliente.getId() != 0) {
            persistenceServices.update(cliente);
        } else {
            persistenceServices.create(cliente);
        }
    }

    /**
     * Permite eliminar un cliente
     * @param cliente
     */
    @RolesAllowed({"Administrador"})
    public void delete(Cliente cliente) {
        persistenceServices.delete(cliente);
    }

    /**
     * Realiza una busqueda para comprobar si un numero de documento ya fue
     * ingresado
     * @param documento
     * @return
     */
    public boolean existeDocumento(String documento) {
        String sql = "Select c from Cliente c where c.documento = :pDocumento ";
        List lista = persistenceServices.findQuery(sql, "pDocumento", documento);

        return lista.size() > 0;
    }

    /**
     * Obtiene una lista de todos los clientes
     * @return
     */
    public List findAllClientes() {
        return persistenceServices.findAll(Cliente.class);
    }

    /**
     * Permite realizar una lista de clientes basados en una serie de parametros
     * @param clienteBusqueda
     * @return
     */
    public List<Cliente> findClientes(Cliente clienteBusqueda) {
        String sql = "Select c from Cliente c where 1=1 ";

        ArrayList<String> parametrosNombre = new ArrayList<String>();
        ArrayList<Object> parametrosValor = new ArrayList<Object>();

        if (clienteBusqueda.getCiudadResidencia() != null) {
            sql += " and c.ciudadResidencia = :pCiudad";
            parametrosNombre.add("pCiudad");
            parametrosValor.add(clienteBusqueda.getCiudadResidencia());
        }

        if (clienteBusqueda.getDireccion() != null && !clienteBusqueda.getDireccion().equals("")) {
            sql += " and c.direccion like :pDireccion";
            parametrosNombre.add("pDireccion");
            parametrosValor.add("%" + clienteBusqueda.getDireccion() + "%");
        }

        if (clienteBusqueda.getDocumento() != null && !clienteBusqueda.getDocumento().equals("")) {
            sql += " and c.documento like :pDocumento";
            parametrosNombre.add("pDocumento");
            parametrosValor.add("%" + clienteBusqueda.getDocumento() + "%");
        }

        if (clienteBusqueda.getEmail() != null && !clienteBusqueda.getEmail().equals("")) {
            sql += " and c.email like :pEMail";
            parametrosNombre.add("pEMail");
            parametrosValor.add("%" + clienteBusqueda.getEmail() + "%");
        }

        if (clienteBusqueda.getNombre() != null && !clienteBusqueda.getNombre().equals("")) {
            sql += " and c.nombre like :pNombre";
            parametrosNombre.add("pNombre");
            parametrosValor.add("%" + clienteBusqueda.getNombre() + "%");
        }

        if (clienteBusqueda.getProfesion() != null && !clienteBusqueda.getProfesion().equals("")) {
            sql += " and c.profesion like :pProfesion";
            parametrosNombre.add("pProfesion");
            parametrosValor.add("%" + clienteBusqueda.getProfesion() + "%");
        }

        if (clienteBusqueda.getTelefonoCelular() != null && !clienteBusqueda.getTelefonoCelular().equals("")) {
            sql += " and c.telefonoCelular like :pTelefonoCelular";
            parametrosNombre.add("pTelefonoCelular");
            parametrosValor.add("%" + clienteBusqueda.getTelefonoCelular() + "%");
        }

        if (clienteBusqueda.getTelefonoResidencia() != null && !clienteBusqueda.getTelefonoResidencia().equals("")) {
            sql += " and c.telefonoResidencia like :pTelefonoResidencia";
            parametrosNombre.add("pTelefonoResidencia");
            parametrosValor.add("%" + clienteBusqueda.getTelefonoResidencia() + "%");
        }

        if (clienteBusqueda.getTipoDocumento() != null && !clienteBusqueda.getTipoDocumento().equals("Seleccione")) {
            sql += " and c.tipoDocumento like = pTipoDocumento";
            parametrosNombre.add("pTipoDocumento");
            parametrosValor.add(clienteBusqueda.getTipoDocumento());
        }


        return persistenceServices.findQuery(sql, parametrosNombre, parametrosValor);
    }

    /**
     * Obtiene un cliente a partir del nombre, esto se utiliza para realizar
     * el login
     * @param nombre
     * @return
     */
    public Cliente getCliente(String nombre) {
        String sql = "Select c from Cliente c where c.nombre = :pNombre ";


        List lista = persistenceServices.findQuery(sql, "pNombre", nombre);
        if (lista.size() > 0) {
            return (Cliente) lista.get(0);
        } else {
            return null;
        }
    }

    /**
     * Obtiene un cliente a partir del documento
     * @param documento
     * @return
     */
    public Cliente getClienteByDocumento(String documento) {
        String sql = "Select c from Cliente c where c.documento = :pDocumento ";


        List lista = persistenceServices.findQuery(sql, "pDocumento", documento);
        if (lista.size() > 0) {
            return (Cliente) lista.get(0);
        } else {
            return null;
        }
    }

    /**
     * Obtiene un cliente a partir de la identificacion
     * @param documento
     * @return
     */
    public Cliente getCliente(Long id) {
        return (Cliente) persistenceServices.findById(Cliente.class, id);
    }

    /**
     * Obtiene la lista de tipos de documento
     * @return
     */
    public SelectItem[] getTiposDocumentos() {
        TipoDocumento[] tipos = TipoDocumento.values();
        SelectItem[] sitems = new SelectItem[tipos.length];
        for (int i = 0; i < sitems.length; i++) {
            sitems[i] = new SelectItem(tipos[i]);
        }
        return sitems;
    }

    /**
     * Obtiene la lista de paises
     * @return
     */
    public SelectItem[] getPaises() {
        ArrayList<SelectItem> items = new ArrayList<SelectItem>();
        for (Pais pais : (List<Pais>) persistenceServices.findAll(Pais.class)) {
            items.add(new SelectItem(pais.getId(), pais.getNombre()));
        }

        SelectItem[] c = new SelectItem[items.size()];
        return items.toArray(c);
    }

    /**
     * Obtiene la lista de departamentos
     * @param pais
     * @return
     */
    public SelectItem[] getDepartamentos(int pais) {

        Pais opais = getPaisById(pais);

        ArrayList<SelectItem> items = new ArrayList<SelectItem>();
        for (Departamento departamento : (List<Departamento>) persistenceServices.findAll(Departamento.class)) {
            if (opais != null && opais.equals(departamento.getPais())) {
                items.add(new SelectItem(departamento.getId(), departamento.getNombre()));
            }
        }

        SelectItem[] c = new SelectItem[items.size()];
        return items.toArray(c);
    }

    /**
     * Obtiene la lista de ciudades
     * @param departamento
     * @param pais
     * @return
     */
    public SelectItem[] getCiudades(int departamento, int pais) {
        ArrayList<SelectItem> items = new ArrayList<SelectItem>();

        Departamento odepartamento = getDepartamentoById(departamento);
        if (odepartamento != null && odepartamento.getPais() != null && odepartamento.getPais().getId() != pais) {
            odepartamento = getDepartamentoById(0);
        }

        for (Ciudad ciudad : (List<Ciudad>) persistenceServices.findAll(Ciudad.class)) {
            if (odepartamento != null && odepartamento.equals(ciudad.getDepartamento())) {
                items.add(new SelectItem(ciudad.getId(), ciudad.getNombre()));
            }
        }

        SelectItem[] c = new SelectItem[items.size()];
        return items.toArray(c);
    }

    /**
     * Obtiene el Pais a partir del identificador
     * @param id
     * @return
     */
    public Pais getPaisById(Integer id) {
        return (Pais) persistenceServices.findById(Pais.class, id);
    }

    /**
     * Obtiene el departamento a partir del identificador
     * @param id
     * @return
     */
    public Departamento getDepartamentoById(Integer id) {
        return (Departamento) persistenceServices.findById(Departamento.class, id);
    }

    /**
     * Obtiene la ciudad a partir de la identificacion
     * @param id
     * @return
     */
    public Ciudad getCiudadById(Integer id) {
        return (Ciudad) persistenceServices.findById(Ciudad.class, id);
    }
}